package com.example.emoteme;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class Face extends Activity {
	InputStream in = null;
	private static final int SERVERPORT = 9999;
	private static final String SERVER_IP = "192.168.1.211";
	// Paint paintCejas;
	Point cejaIzq;
	Point cejaDer;
	Point mouth;
	Point nose;
	Point ojoIzq;
	Point ojoDer;
	int separacionCejas = 140;
	int tamCeja = 80;
	int tamBocaIni = 100;
	private ServerSocket SkServer;
	private Socket SkClient;
	private float scaleFactor = 1;
	Display display;
	Cara cara;

	// JSON Node names
	private static final String TAG_CARAS = "cara";
	private static final String TAG_GRADO_CEJA_IZQ = "gradoCejaIzq";
	private static final String TAG_GRADO_CEJA_DRCH = "gradoCejaDer";
	private static final String TAG_GRADO_BOCA = "gradoBoca";
	private static final String TAG_APERTURA_BOCA = "aperturaBoca";
	private static final String TAG_TAM_BOCA = "tamBoca";
	private static final String TAG_ESTADO_BOCA = "estadoBoca";
	private static final String TAG_POS_OJO_IZQ_X = "posOjoIzqX";
	private static final String TAG_POS_OJO_IZQ_Y = "posOjoIzqY";
	private static final String TAG_POS_OJO_DRCH_X = "posOjoDerX";
	private static final String TAG_POS_OJO_DRCH_Y = "posOjoDerY";

	class RenderView extends View {
		Paint paintCejas;
		Paint paintBoca;
		Paint paintOjos;

		Canvas canvasBoca;
		Canvas canvasCejaIzq;
		Canvas canvasCejaDer;
		Canvas canvasOjos;
		Bitmap bm = Bitmap.createBitmap(display.getWidth(),
				display.getHeight(), Bitmap.Config.ARGB_8888);;

		public RenderView(Context context) {
			super(context);
			paintCejas = new Paint();
			paintBoca = new Paint();
			paintOjos = new Paint();
		}

		protected void onDraw(Canvas canvas) {
			canvas.drawRGB(255, 255, 255);
			canvasBoca = canvas;
			canvasCejaIzq = canvas;
			canvasCejaDer = canvas;
			canvasOjos = canvas;
			paintCejas.setColor(Color.BLACK);
			paintCejas.setStyle(Style.STROKE);
			paintBoca.setColor(Color.RED);
			paintOjos.setColor(Color.BLUE);
			paintOjos.setStyle(Style.FILL);
			// Draw eyes
			pintaOjos(cara.getPosOjoIzqX(), cara.getPosOjoIzqY(),
					cara.getPosOjoDerX(), cara.getPosOjoDerY(), canvasOjos);

			// Draw nose
			canvas.drawLine(nose.x, nose.y - 100*scaleFactor, nose.x - 30*scaleFactor, nose.y,
					paintCejas);
			canvas.drawLine(nose.x - 30*scaleFactor, nose.y, nose.x, nose.y + 30*scaleFactor,
					paintCejas);
			canvas.drawLine(nose.x, nose.y + 30*scaleFactor, nose.x + 30*scaleFactor, nose.y,
					paintCejas);
			canvas.drawLine(nose.x + 30*scaleFactor, nose.y, nose.x, nose.y, paintCejas);

			pintaBoca(cara.getAperturaBoca(), canvasBoca, cara.getEstadoBoca(),
					cara.getGradoBoca());
			pintaCejas(cara.getGradoCejaIzq(), cara.getGradoCejaDer(),
					canvasCejaIzq, canvasCejaDer);
			invalidate();
		}

		private void pintaOjos(int ojoIzqX, int ojoIzqY, int ojoDerX,
				int ojoDerY, Canvas canvas) {

			canvas.save();

			RectF rectOjoDer = new RectF(cejaDer.x, cejaDer.y + 5*scaleFactor, cejaDer.x
					+ tamCeja*scaleFactor, cejaDer.y + 35*scaleFactor);
			RectF rectOjoIzq = new RectF(cejaIzq.x, cejaIzq.y + 5*scaleFactor, cejaIzq.x
					+ tamCeja*scaleFactor, cejaIzq.y + 35*scaleFactor);
			canvas.drawCircle(ojoIzq.x+ojoIzqX, ojoIzq.y+ojoIzqY, 3*scaleFactor, paintOjos);
			canvas.drawCircle(ojoDer.x+ojoDerX, ojoDer.y+ojoDerY, 3*scaleFactor, paintOjos);
			canvas.drawOval(rectOjoIzq, paintCejas);
			canvas.drawOval(rectOjoDer, paintCejas);
			
			canvas.restore();

		}

		private void pintaBoca(float distFoc, Canvas canvasboca,
				int estadoBoca, float angulo) {
			canvasboca.save();
			RectF rect = new RectF(mouth.x, mouth.y - distFoc, mouth.x
					+ (cara.getTamBoca()*scaleFactor), mouth.y + distFoc);
			canvasboca.rotate(angulo, mouth.x + (cara.getTamBoca() / 2)*scaleFactor,
					mouth.y);
			switch (estadoBoca) {
			case -1:
				//canvasboca.drawArc(rect, 0, 180, true, paintBoca);
				canvasboca.rotate(180, mouth.x + (cara.getTamBoca() / 2)*scaleFactor,
						mouth.y);
				//break;
			case 1:
				canvasboca.drawArc(rect, 0, 180, true, paintBoca);
				break;
			default:
				canvasboca.drawOval(rect, paintBoca);
				break;
			}
			canvasboca.restore();
		}

		private void pintaCejas(float gradoIzq, float gradoDer, Canvas CejaIzq,
				Canvas CejaDer) {
			CejaIzq.save();
			CejaIzq.rotate(gradoIzq, cejaIzq.x + (tamCeja / 2)*scaleFactor, cejaIzq.y);

			CejaIzq.drawLine(cejaIzq.x, cejaIzq.y, cejaIzq.x + tamCeja*scaleFactor,
					cejaIzq.y, paintCejas);
			
			CejaIzq.restore();
			CejaDer.save();
			CejaDer.rotate(gradoDer, cejaDer.x + (tamCeja / 2)*scaleFactor, cejaDer.y);
			CejaDer.drawLine(cejaDer.x, cejaDer.y, cejaDer.x + tamCeja*scaleFactor,
					cejaDer.y, paintCejas);
			
			CejaDer.restore();
		}
	}

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		display = getWindowManager().getDefaultDisplay();
		float ratio = (float) 800 / 480;
		scaleFactor = (float) ratio
				/ (float) ((display.getWidth() / display.getHeight()));
		nose = new Point(display.getWidth() / 2, display.getHeight() / 2);
		mouth = new Point((display.getWidth()/2) - (int)((tamBocaIni / 2)*scaleFactor), (display.getHeight()/2) + (int) (80*scaleFactor));
		cejaIzq = new Point((display.getWidth() / 2) - (int)(separacionCejas*scaleFactor), (display.getHeight() / 2) - (int)(100*scaleFactor));
		cejaDer = new Point((display.getWidth() / 2) + (int)((separacionCejas - tamCeja)*scaleFactor),
				(display.getHeight() / 2) - (int)(100*scaleFactor));
		
		ojoIzq = new Point(cejaIzq.x+(int)((tamCeja/2)*scaleFactor ),cejaIzq.y+(int)(15*scaleFactor) );
		ojoDer = new Point(cejaDer.x+(int)((tamCeja/2)*scaleFactor ),cejaIzq.y+(int)(15*scaleFactor) );
		

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(new RenderView(this));

	}
	public void onStart(){
		super.onStart();
		try {
			SkServer = new ServerSocket(SERVERPORT);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		new Thread(new changeFace()).start();
	}
	class changeFace implements Runnable {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				cara = new Cara();
				cara.setParams(0, 0, 0, 20, 100,-1,0,0,0,0);
				
				while (true) {
					System.out.println("Dentro del bucle");
					try{
						
						SkClient = SkServer.accept();
						
					}
					catch (IOException e) {
						System.out.println("Segundo catch");
						continue;
					}
					System.out.println("He creado el socket con el server");
					ObjectInputStream ois = new ObjectInputStream(
							SkClient.getInputStream());
					System.out.println("He creado un inputsream del socket");
					 
					Object o = null;
					
					if (ois != null)
						o = ois.readObject();

					if (o != null) {
						System.out.println("<----Objeto recibido");
						JSONObject jsonObj;
						try {
							jsonObj = new JSONObject((String) o);
							JSONArray arrayDatos = jsonObj
									.getJSONArray(TAG_CARAS);
							JSONObject objeto = arrayDatos.getJSONObject(0);

							int aperturaBoca = objeto.getInt(TAG_APERTURA_BOCA);
							int estadoBoca = objeto.getInt(TAG_ESTADO_BOCA);
							int gradoBoca = objeto.getInt(TAG_GRADO_BOCA);
							int gradoCejaDerecha = objeto
									.getInt(TAG_GRADO_CEJA_DRCH);
							int gradoCejaIzquierda = objeto
									.getInt(TAG_GRADO_CEJA_IZQ);
							int posOjoDerechoX = objeto
									.getInt(TAG_POS_OJO_DRCH_X);
							int posOjoDerechoY = objeto
									.getInt(TAG_POS_OJO_DRCH_Y);
							int posOjoIzquierdoX = objeto
									.getInt(TAG_POS_OJO_IZQ_X);
							int posOjoIzquierdoY = objeto
									.getInt(TAG_POS_OJO_IZQ_Y);
							int tamanoBoca = objeto.getInt(TAG_TAM_BOCA);
							
							cara.setParams(gradoCejaIzquierda, gradoCejaDerecha, gradoBoca, aperturaBoca, tamanoBoca,
									estadoBoca, posOjoIzquierdoX, posOjoIzquierdoY, posOjoDerechoX, posOjoDerechoY);

						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
						
					}
					
				}

			} catch (UnknownHostException e) {
				System.out.println("primer catch");
				e.printStackTrace();
			} catch (IOException e) {
				System.out.println("Segundo catchx");
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				System.out.println("tercer catch");
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}
